use anyhow::{Ok, Result};
// use dotenvy::dotenv;
// use helpers::Bot;
// use teloxide::{dispatching::UpdateFilterExt, prelude::*, types::Update};
use helpers::DatabaseConnection;
use std::{ops::Deref, sync::Arc};
use tokio::sync::Mutex;
mod db;
mod handlers;
mod helpers;
mod models;

#[tokio::main(flavor = "multi_thread", worker_threads = 20)]
async fn main() {
    // Get values from .env file
    // dotenv().ok();
    let db = Arc::new(Mutex::new(db::connect_to_db().await.unwrap()));
    run_bot(db).await;
}

use matrix_sdk::{
    config::SyncSettings,
    event_handler::Ctx,
    room::Room,
    ruma::events::room::message::{
        MessageType, OriginalSyncRoomMessageEvent, RoomMessageEventContent,
    },
    Client,
};
async fn messages_handler(
    event: OriginalSyncRoomMessageEvent,
    room: Room,
    client: Client,
    db: Ctx<DatabaseConnection>,
) -> Result<()> {
    if let Room::Joined(room) = room {
        if event.sender != *client.user_id().unwrap() {
            match event.content.msgtype.clone() {
                MessageType::Text(message) => {
                    let text = {
                        if let Some(formatted_message) = message.formatted {
                            formatted_message.body
                        } else {
                            message.body
                        }
                    };
                    if text.contains("!party") {
                        let content =
                            RoomMessageEventContent::text_plain("🎉🎊🥳 let's PARTY!! 🥳🎊🎉");

                        println!("sending");

                        // send our message to the room we found the "!party" command in
                        // the last parameter is an optional transaction id which we don't
                        // care about.
                        room.send(content, None).await?;

                        println!("message sent");
                        //   Ok(())
                    } else if text.contains("!archive") {
                        handlers::archive(event, text, room, client, db.deref().clone()).await?;
                    } else if text.contains("!unarchive") {
                        handlers::unarchive(event, text, room, client, db.deref().clone()).await?;
                    } else if text.contains("!random") {
                        handlers::random(event, text, room, client, db.deref().clone()).await?;
                    } else if text.contains("!delete") {
                        handlers::delete(event, text, room, client, db.deref().clone()).await?;
                    } else if text.contains("!favorite") {
                        handlers::favorite(event, text, room, client, db.deref().clone()).await?;
                    } else if text.contains("!unfavorite") {
                        handlers::unfavorite(event, text, room, client, db.deref().clone()).await?;
                    } else if text.contains("!count_unread_time") {
                        handlers::count_unread_time(event, text, room, client, db.deref().clone())
                            .await?;
                    } else if text.contains("!count_unread") {
                        handlers::count_unread_posts(event, text, room, client, db.deref().clone())
                            .await?;
                    } else if text.contains("!show_real_url") {
                        handlers::show_real_url(event, text, room, client, db.deref().clone())
                            .await?;
                    } else if text.contains("!show_alternative_url") {
                        handlers::show_alternative_url(
                            event,
                            text,
                            room,
                            client,
                            db.deref().clone(),
                        )
                        .await?;
                    } else {
                        handlers::add(event, text, room, client, db.deref().clone()).await?;
                        //Ok(())
                    }
                }
                _ => return Ok(()),
            };
        }
    }
    Ok(())
}

// use tokio_postgres::Client as DatabaseConnection;
async fn run_bot(db: DatabaseConnection) {
    pretty_env_logger::formatted_builder()
        .filter(
            Some(&env!("CARGO_CRATE_NAME").replace('-', "_")),
            log::LevelFilter::Info,
        )
        .filter(Some("matrix"), log::LevelFilter::Info)
        //.target(pretty_env_logger::env_logger::Target::Stdout)
        .init();
    log::info!("Starting readlaterbot...");
    // let bot_name = std::env::var("BOT_NAME").unwrap();
    // let user_id = user_id!(bot_name);
    let homeserver_url = std::env::var("MATRIX_HOMESERVER_URL").unwrap();
    let username = std::env::var("MATRIX_USERNAME").unwrap();
    let password = std::env::var("MATRIX_PASSWORD").unwrap();
    // login_and_sync(homeserver_url, &username, &password).await?;
    let mut client_builder = Client::builder().homeserver_url(homeserver_url);
    let home = dirs::home_dir()
        .expect("no home directory found")
        .join("readlater_bot");
    client_builder = client_builder.sled_store(home, None);
    let client = client_builder.build().await.unwrap();
    client
        .login_username(&username, &password)
        .initial_device_display_name("readlaterbot")
        .send()
        .await
        .unwrap();
    let response = client.sync_once(SyncSettings::default()).await.unwrap();
    let settings = SyncSettings::default().token(response.next_batch);
    client.add_event_handler_context(db);
    client.add_event_handler(messages_handler);
    client.sync(settings).await.unwrap();
}
